function ownKeys(object, enumerableOnly) {
  var keys = Object.keys(object);

  if (Object.getOwnPropertySymbols) {
    var symbols = Object.getOwnPropertySymbols(object);
    enumerableOnly && (symbols = symbols.filter(function (sym) {
      return Object.getOwnPropertyDescriptor(object, sym).enumerable;
    })), keys.push.apply(keys, symbols);
  }

  return keys;
}

function _objectSpread2(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = null != arguments[i] ? arguments[i] : {};
    i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
      _defineProperty(target, key, source[key]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
      Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
    });
  }

  return target;
}

function _regeneratorRuntime() {
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */

  _regeneratorRuntime = function () {
    return exports;
  };

  var exports = {},
      Op = Object.prototype,
      hasOwn = Op.hasOwnProperty,
      $Symbol = "function" == typeof Symbol ? Symbol : {},
      iteratorSymbol = $Symbol.iterator || "@@iterator",
      asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
      toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

  function define(obj, key, value) {
    return Object.defineProperty(obj, key, {
      value: value,
      enumerable: !0,
      configurable: !0,
      writable: !0
    }), obj[key];
  }

  try {
    define({}, "");
  } catch (err) {
    define = function (obj, key, value) {
      return obj[key] = value;
    };
  }

  function wrap(innerFn, outerFn, self, tryLocsList) {
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
        generator = Object.create(protoGenerator.prototype),
        context = new Context(tryLocsList || []);
    return generator._invoke = function (innerFn, self, context) {
      var state = "suspendedStart";
      return function (method, arg) {
        if ("executing" === state) throw new Error("Generator is already running");

        if ("completed" === state) {
          if ("throw" === method) throw arg;
          return doneResult();
        }

        for (context.method = method, context.arg = arg;;) {
          var delegate = context.delegate;

          if (delegate) {
            var delegateResult = maybeInvokeDelegate(delegate, context);

            if (delegateResult) {
              if (delegateResult === ContinueSentinel) continue;
              return delegateResult;
            }
          }

          if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
            if ("suspendedStart" === state) throw state = "completed", context.arg;
            context.dispatchException(context.arg);
          } else "return" === context.method && context.abrupt("return", context.arg);
          state = "executing";
          var record = tryCatch(innerFn, self, context);

          if ("normal" === record.type) {
            if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
            return {
              value: record.arg,
              done: context.done
            };
          }

          "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
        }
      };
    }(innerFn, self, context), generator;
  }

  function tryCatch(fn, obj, arg) {
    try {
      return {
        type: "normal",
        arg: fn.call(obj, arg)
      };
    } catch (err) {
      return {
        type: "throw",
        arg: err
      };
    }
  }

  exports.wrap = wrap;
  var ContinueSentinel = {};

  function Generator() {}

  function GeneratorFunction() {}

  function GeneratorFunctionPrototype() {}

  var IteratorPrototype = {};
  define(IteratorPrototype, iteratorSymbol, function () {
    return this;
  });
  var getProto = Object.getPrototypeOf,
      NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
  var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);

  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function (method) {
      define(prototype, method, function (arg) {
        return this._invoke(method, arg);
      });
    });
  }

  function AsyncIterator(generator, PromiseImpl) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);

      if ("throw" !== record.type) {
        var result = record.arg,
            value = result.value;
        return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
          invoke("next", value, resolve, reject);
        }, function (err) {
          invoke("throw", err, resolve, reject);
        }) : PromiseImpl.resolve(value).then(function (unwrapped) {
          result.value = unwrapped, resolve(result);
        }, function (error) {
          return invoke("throw", error, resolve, reject);
        });
      }

      reject(record.arg);
    }

    var previousPromise;

    this._invoke = function (method, arg) {
      function callInvokeWithMethodAndArg() {
        return new PromiseImpl(function (resolve, reject) {
          invoke(method, arg, resolve, reject);
        });
      }

      return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
    };
  }

  function maybeInvokeDelegate(delegate, context) {
    var method = delegate.iterator[context.method];

    if (undefined === method) {
      if (context.delegate = null, "throw" === context.method) {
        if (delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel;
        context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method");
      }

      return ContinueSentinel;
    }

    var record = tryCatch(method, delegate.iterator, context.arg);
    if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
    var info = record.arg;
    return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
  }

  function pushTryEntry(locs) {
    var entry = {
      tryLoc: locs[0]
    };
    1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
  }

  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal", delete record.arg, entry.completion = record;
  }

  function Context(tryLocsList) {
    this.tryEntries = [{
      tryLoc: "root"
    }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
  }

  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) return iteratorMethod.call(iterable);
      if ("function" == typeof iterable.next) return iterable;

      if (!isNaN(iterable.length)) {
        var i = -1,
            next = function next() {
          for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;

          return next.value = undefined, next.done = !0, next;
        };

        return next.next = next;
      }
    }

    return {
      next: doneResult
    };
  }

  function doneResult() {
    return {
      value: undefined,
      done: !0
    };
  }

  return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
    var ctor = "function" == typeof genFun && genFun.constructor;
    return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
  }, exports.mark = function (genFun) {
    return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
  }, exports.awrap = function (arg) {
    return {
      __await: arg
    };
  }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
    return this;
  }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
    void 0 === PromiseImpl && (PromiseImpl = Promise);
    var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
    return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
      return result.done ? result.value : iter.next();
    });
  }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
    return this;
  }), define(Gp, "toString", function () {
    return "[object Generator]";
  }), exports.keys = function (object) {
    var keys = [];

    for (var key in object) keys.push(key);

    return keys.reverse(), function next() {
      for (; keys.length;) {
        var key = keys.pop();
        if (key in object) return next.value = key, next.done = !1, next;
      }

      return next.done = !0, next;
    };
  }, exports.values = values, Context.prototype = {
    constructor: Context,
    reset: function (skipTempReset) {
      if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
    },
    stop: function () {
      this.done = !0;
      var rootRecord = this.tryEntries[0].completion;
      if ("throw" === rootRecord.type) throw rootRecord.arg;
      return this.rval;
    },
    dispatchException: function (exception) {
      if (this.done) throw exception;
      var context = this;

      function handle(loc, caught) {
        return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
      }

      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i],
            record = entry.completion;
        if ("root" === entry.tryLoc) return handle("end");

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc"),
              hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
            if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
          } else {
            if (!hasFinally) throw new Error("try statement without catch or finally");
            if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
          }
        }
      }
    },
    abrupt: function (type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];

        if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
      var record = finallyEntry ? finallyEntry.completion : {};
      return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
    },
    complete: function (record, afterLoc) {
      if ("throw" === record.type) throw record.arg;
      return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
    },
    finish: function (finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
      }
    },
    catch: function (tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];

        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;

          if ("throw" === record.type) {
            var thrown = record.arg;
            resetTryEntry(entry);
          }

          return thrown;
        }
      }

      throw new Error("illegal catch attempt");
    },
    delegateYield: function (iterable, resultName, nextLoc) {
      return this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
    }
  }, exports;
}

function _typeof(obj) {
  "@babel/helpers - typeof";

  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
    return typeof obj;
  } : function (obj) {
    return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  }, _typeof(obj);
}

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }

  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}

function _asyncToGenerator(fn) {
  return function () {
    var self = this,
        args = arguments;
    return new Promise(function (resolve, reject) {
      var gen = fn.apply(self, args);

      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }

      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }

      _next(undefined);
    });
  };
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  Object.defineProperty(Constructor, "prototype", {
    writable: false
  });
  return Constructor;
}

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

function _slicedToArray(arr, i) {
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}

function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}

function _iterableToArrayLimit(arr, i) {
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];

  if (_i == null) return;
  var _arr = [];
  var _n = true;
  var _d = false;

  var _s, _e;

  try {
    for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
      _arr.push(_s.value);

      if (i && _arr.length === i) break;
    }
  } catch (err) {
    _d = true;
    _e = err;
  } finally {
    try {
      if (!_n && _i["return"] != null) _i["return"]();
    } finally {
      if (_d) throw _e;
    }
  }

  return _arr;
}

function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}

function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;

  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

  return arr2;
}

function _nonIterableRest() {
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

function _createForOfIteratorHelper(o, allowArrayLike) {
  var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];

  if (!it) {
    if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
      if (it) o = it;
      var i = 0;

      var F = function () {};

      return {
        s: F,
        n: function () {
          if (i >= o.length) return {
            done: true
          };
          return {
            done: false,
            value: o[i++]
          };
        },
        e: function (e) {
          throw e;
        },
        f: F
      };
    }

    throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }

  var normalCompletion = true,
      didErr = false,
      err;
  return {
    s: function () {
      it = it.call(o);
    },
    n: function () {
      var step = it.next();
      normalCompletion = step.done;
      return step;
    },
    e: function (e) {
      didErr = true;
      err = e;
    },
    f: function () {
      try {
        if (!normalCompletion && it.return != null) it.return();
      } finally {
        if (didErr) throw err;
      }
    }
  };
}

var cache = [];
function getCache() {
  return cache;
}
function addCache(data) {
  cache.push(data);
}
function clearCache() {
  cache.length = 0;
}

var timer = null;
/**
 * 上报
 * @param {*} type 
 * @param {*} params 
 */

function lazyReport(type, params) {
  var appId = window['_monitor_app_id_'];
  var userId = window['_monitor_user_id_'];
  var delay = window['_monitor_delay_'];
  var userinfo = window['_monitor_user_info_'];
  console.log('reportData', params);
  var logParams = {
    appId: appId,
    // 项目的appId
    userId: userId,
    // 用户id
    userinfo: userinfo,
    type: type,
    // error/action/visit/user
    data: params,
    // 上报的数据
    currentTime: new Date().getTime(),
    // 时间戳
    currentPage: window.location.href,
    // 当前页面
    ua: navigator.userAgent // ua信息

  };
  var logParamsString = JSON.stringify(logParams);
  addCache(logParamsString);
  var data = getCache();

  if (delay === 0) {
    // delay=0相当于不做延迟上报
    report$1(data);
    return;
  }

  if (data.length > 10) {
    report$1(data);
    clearTimeout(timer);
    return;
  }

  clearTimeout(timer);
  timer = setTimeout(function () {
    report$1(data);
  }, delay);
}
function report$1(data) {
  var url = window['_monitor_report_url_']; // ------- fetch方式上报 -------
  // 跨域问题
  // fetch(url, {
  //   method: 'POST',
  //   body: JSON.stringify(data),
  //   headers: {
  //     'Content-Type': 'application/json',
  //   },
  // }).then(res => {
  //   console.log(res);
  // }).catch(err => {
  //   console.error(err);
  // })
  // ------- navigator/img方式上报 -------
  // 不会有跨域问题

  if (navigator.sendBeacon) {
    // 支持sendBeacon的浏览器
    navigator.sendBeacon(url, JSON.stringify(data));
  } else {
    // 不支持sendBeacon的浏览器
    var oImage = new Image();
    oImage.src = "".concat(url, "?logs=").concat(data);
  }

  clearCache();
}

/**
 * 手动上报
 */

function tracker(actionType, data) {
  lazyReport('action', {
    actionType: actionType,
    data: data
  });
}
/**
 * 自动上报
 */

function autoTrackerReport() {
  // 自动上报
  document.body.addEventListener('click', function (e) {
    var clickedDom = e.target; // 获取标签上的data-target属性的值

    var target = clickedDom === null || clickedDom === void 0 ? void 0 : clickedDom.getAttribute('data-target'); // 获取标签上的data-no属性的值

    var no = clickedDom === null || clickedDom === void 0 ? void 0 : clickedDom.getAttribute('data-no'); // 避免重复上报

    if (no) {
      return;
    }

    if (target) {
      lazyReport('action', {
        actionType: 'manual',
        data: target
      });
    } else {
      // 获取被点击元素的dom路径
      var result = getImgButtonPath(clickedDom);

      if (result) {
        var node = result.node;
        lazyReport('action', {
          actionType: node,
          data: result
        });
      }
    }
  }, false);
}

/**
 * history路由监听
 */

function historyPageTrackerReport() {
  var beforeTime = Date.now(); // 进入页面的时间

  var beforePage = ''; // 上一个页面
  // 获取在某个页面的停留时间

  function getStayTime() {
    var curTime = Date.now();
    var stayTime = curTime - beforeTime;
    beforeTime = curTime;
    return stayTime;
  }
  /**
   * 重写pushState和replaceState方法
   * @param {*} name 
   * @returns 
   */


  var createHistoryEvent = function createHistoryEvent(name) {
    // 拿到原来的处理方法
    var origin = window.history[name];
    return function (event) {
      // if (name === 'replaceState') {
      //   const { current } = event;
      //   const pathName = location.pathname;
      //   if (current === pathName) {
      //     let res = origin.apply(this, arguments);
      //     return res;
      //   }
      // }
      var res = origin.apply(this, arguments);
      var e = new Event(name);
      e.arguments = arguments;
      window.dispatchEvent(e);
      return res;
    };
  }; // history.pushState


  window.addEventListener('pushState', function () {
    listener();
  }); // history.replaceState

  window.addEventListener('replaceState', function () {
    listener();
  });
  window.history.pushState = createHistoryEvent('pushState');
  window.history.replaceState = createHistoryEvent('replaceState');

  function listener() {
    var stayTime = getStayTime(); // 停留时间

    var currentPage = window.location.href; // 页面路径

    lazyReport('visit', {
      stayTime: stayTime,
      page: beforePage
    });
    beforePage = currentPage;
  } // 页面load监听


  window.addEventListener('load', function () {
    // beforePage = location.href;
    listener();
  }); // unload监听

  window.addEventListener('unload', function () {
    listener();
  }); // history.go()、history.back()、history.forward() 监听

  window.addEventListener('popstate', function () {
    listener();
  });
}
/**
 * hash路由监听
 */

function hashPageTrackerReport() {
  var beforeTime = Date.now(); // 进入页面的时间

  var beforePage = ''; // 上一个页面

  function getStayTime() {
    var curTime = Date.now();
    var stayTime = curTime - beforeTime;
    beforeTime = curTime;
    return stayTime;
  }

  function listener() {
    var stayTime = getStayTime();
    var currentPage = window.location.href;
    lazyReport('visit', {
      stayTime: stayTime,
      page: beforePage
    });
    beforePage = currentPage;
  } // hash路由监听


  window.addEventListener('hashchange', function () {
    listener();
  }); // 页面load监听

  window.addEventListener('load', function () {
    listener();
  });

  var createHistoryEvent = function createHistoryEvent(name) {
    var origin = window.history[name];
    return function (event) {
      // if (name === 'replaceState') {
      //   const { current } = event;
      //   const pathName = location.pathname;
      //   if (current === pathName) {
      //     let res = origin.apply(this, arguments);
      //     return res;
      //   }
      // }
      var res = origin.apply(this, arguments);
      var e = new Event(name);
      e.arguments = arguments;
      window.dispatchEvent(e);
      return res;
    };
  };

  window.history.pushState = createHistoryEvent('pushState'); // history.pushState

  window.addEventListener('pushState', function () {
    listener();
  });
}

/**
 * 全局错误捕获
 */

function errorTrackerReport() {
  // --------  js error ---------
  var originOnError = window.onerror;

  window.onerror = function (msg, url, row, col, error) {
    // 处理原有的onerror
    if (originOnError) {
      originOnError.call(window, msg, url, row, col, error);
    } // 错误上报


    lazyReport('error', {
      message: msg,
      file: url,
      row: row,
      col: col,
      error: String(error),
      errorType: 'jsError'
    });
  }; // ------  promise error  --------


  window.addEventListener('unhandledrejection', function (error) {
    error.preventDefault();
    lazyReport('error', {
      message: formatError(error.reason),
      error: error,
      errorType: 'promiseError'
    });
  }); //格式化Error

  function formatError(error) {
    if (error instanceof Error) {
      return JSON.stringify({
        name: error.name,
        message: error.message,
        stack: error.stack // 包含代码位置的关键信息

      }, null, 2);
    }

    return String(error); // 非Error对象的回退方案
  } // ------- resource error --------


  window.addEventListener('error', function (error) {
    var target = error.target;
    var isElementTarget = target instanceof HTMLScriptElement || target instanceof HTMLLinkElement || target instanceof HTMLImageElement;

    if (!isElementTarget) {
      return; // js error不再处理
    }

    lazyReport('error', {
      message: "加载 " + target.tagName + " 资源错误",
      file: target.src,
      errorType: 'resourceError'
    });
  }, true);
}
/**
 * 手动捕获错误
 */

function errorCaptcher(error, msg) {
  // 上报错误
  lazyReport('error', {
    message: msg,
    error: error,
    errorType: 'catchError'
  });
}

function report(data) {
  lazyReport('http', data);
} // 初始化监控

function httpTrackerReport(regx) {
  interceptXHR(regx);
  interceptFetch(regx);
} // XMLHttpRequest 拦截

function interceptXHR(resRegx) {
  if (typeof XMLHttpRequest === 'undefined') return;
  var originalOpen = XMLHttpRequest.prototype.open;
  var originalSend = XMLHttpRequest.prototype.send;

  XMLHttpRequest.prototype.open = function (method, url) {
    this._method = method;
    this._url = url;
    return originalOpen.apply(this, arguments);
  };

  XMLHttpRequest.prototype.send = function (body) {
    var _this = this;

    var startTime = Date.now();

    var onLoadend = function onLoadend() {
      var _this$responseText;

      var duration = Date.now() - startTime; // 请求数据处理

      var request = handleBody(body);
      var error = '';

      if (_this.status !== 200 || resRegx.test(_this.responseText)) {
        error = error = catResponse(_this.responseText);
      }

      report({
        type: 'xhr',
        method: _this._method,
        url: _this._url,
        status: _this.status,
        duration: duration,
        error: error,
        request: request,
        requestSize: body ? body.length : 0,
        responseSize: ((_this$responseText = _this.responseText) === null || _this$responseText === void 0 ? void 0 : _this$responseText.length) || 0
      });

      _this.removeEventListener('loadend', onLoadend);
    };

    this.addEventListener('loadend', onLoadend);
    return originalSend.apply(this, arguments);
  };
} // Fetch 拦截

function interceptFetch(resRegx) {
  if (typeof fetch === 'undefined') return;
  var originalFetch = window.fetch;

  window.fetch = /*#__PURE__*/function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(input, init) {
      var startTime, url, method, request, _init$body, response, duration, clonedResponse, responseText, error, _duration;

      return _regeneratorRuntime().wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              startTime = Date.now();
              url = typeof input === 'string' ? input : input.url;
              method = ((init === null || init === void 0 ? void 0 : init.method) || 'GET').toUpperCase();
              request = handleBody(init === null || init === void 0 ? void 0 : init.body);
              _context.prev = 4;
              _context.next = 7;
              return originalFetch(input, init);

            case 7:
              response = _context.sent;
              duration = Date.now() - startTime; // 克隆响应以读取数据

              clonedResponse = response.clone();
              _context.next = 12;
              return clonedResponse.text();

            case 12:
              responseText = _context.sent;
              error = '';

              if (response.status !== 200 || resRegx.test(responseText)) {
                error = catResponse(responseText);
              }

              report({
                type: 'fetch',
                method: method,
                url: url,
                status: response.status,
                duration: duration,
                error: error,
                request: request,
                requestSize: (init === null || init === void 0 ? void 0 : (_init$body = init.body) === null || _init$body === void 0 ? void 0 : _init$body.length) || 0,
                responseSize: new Blob([responseText]).size
              });
              return _context.abrupt("return", response);

            case 19:
              _context.prev = 19;
              _context.t0 = _context["catch"](4);
              _duration = Date.now() - startTime;
              report({
                type: 'fetch',
                method: method,
                url: url,
                status: 0,
                // 网络错误
                duration: _duration,
                error: catResponse(_context.t0.message)
              });
              throw _context.t0;

            case 24:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, null, [[4, 19]]);
    }));

    return function (_x, _x2) {
      return _ref.apply(this, arguments);
    };
  }();
}

function handleBody(body) {
  if (body instanceof FormData) {
    return processFormData(body);
  } else {
    return processBodyData(body);
  }
}

function processFormData(formData) {
  if (!formData) {
    return formData;
  }

  var body = {};

  try {
    var _iterator = _createForOfIteratorHelper(formData.entries()),
        _step;

    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var _step$value = _slicedToArray(_step.value, 2),
            name = _step$value[0],
            value = _step$value[1];

        var data = value;

        if (data) {
          if (data instanceof File) {
            var file = {
              fileName: name,
              fileType: data.type,
              fileSize: data.size,
              lastModified: data.lastModified
            };
            body[name] = file;
          } else if (typeof data === "string" && data.length > 100) {
            body[name] = data.substring(0, 100);
          }
        }
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }
  } catch (error) {
    body = formData;
  }

  return body;
}

function processBodyData(bodyData) {
  if (!bodyData) {
    return bodyData;
  }

  var body = "";

  try {
    body = JSON.parse(bodyData);
    Object.keys(body).forEach(function (item) {
      var data = body[item];

      if (data) {
        if (data instanceof File) {
          var file = {
            fileName: data.name,
            fileType: data.type,
            fileSize: data.size,
            lastModified: data.lastModified
          };
          body[item] = file;
        } else if (typeof data === "string" && data.length > 100) {
          body[item] = data.substring(0, 100);
        }
      }
    });
  } catch (error) {
    if (typeof bodyData === "string") {
      body = bodyData.substring(0, 500);
    } else {
      body = bodyData;
    }
  }

  return body;
}

function catResponse(response) {
  if (response) {
    if (_typeof(response) == "object") {
      var str = JSON.stringify(response);
      return str.substring(0, 500);
    } else {
      return response.substring(0, 500);
    }
  }

  return "";
}

/**
 * 加载配置
 * @param {*} options 
 */

function loadConfig(options) {
  var appId = options.appId,
      userId = options.userId,
      reportUrl = options.reportUrl,
      autoTracker = options.autoTracker,
      delay = options.delay,
      hashPage = options.hashPage,
      errorReport = options.errorReport,
      httpReport = options.httpReport,
      responseRegex = options.responseRegex; // --------- appId ----------------

  if (appId) {
    window['_monitor_app_id_'] = appId;
  } // --------- userId ----------------


  if (userId) {
    window['_monitor_user_id_'] = userId;
  } // --------- 服务端地址 ----------------


  if (reportUrl) {
    window['_monitor_report_url_'] = reportUrl;
  } // -------- 合并上报的间隔 ------------


  if (delay) {
    window['_monitor_delay_'] = delay;
  } // --------- 是否开启错误监控 ------------


  if (errorReport) {
    errorTrackerReport();
  } // --------- 是否开启网络请求监控 ------------


  if (httpReport) {
    httpTrackerReport(responseRegex);
  } // --------- 是否开启无痕埋点 ----------


  if (autoTracker) {
    autoTrackerReport();
  } // ----------- 路由监听 --------------


  if (hashPage) {
    hashPageTrackerReport(); // hash路由上报
  } else {
    historyPageTrackerReport(); // history路由上报
  }
}
var getPathTo = function getPathTo(element) {
  if (element.id !== '') return '//*[@id="' + element.id + '"]';
  if (element === document.body) return element.tagName;
  var ix = 0;

  if (element && element.parentNode && element.parentNode.childNodes) {
    var _element$parentNode;

    var siblings = element === null || element === void 0 ? void 0 : (_element$parentNode = element.parentNode) === null || _element$parentNode === void 0 ? void 0 : _element$parentNode.childNodes;

    for (var i = 0; i < siblings.length; i++) {
      var sibling = siblings[i];
      if (sibling === element) return getPathTo(element.parentNode) + '/' + element.tagName + '[' + (ix + 1) + ']';
      if (sibling.nodeType === 1 && sibling.tagName === element.tagName) ix++;
    }
  } else {
    return null;
  }
};
var getPathTo2 = function getPathTo2(element) {
  if (!element) return {
    node: "",
    path: ""
  }; // 基础结果对象 - 确保node永远有值

  var result = {
    node: element.nodeName,
    path: "",
    className: element.className // 直接获取元素自身的类名

  }; // 添加元素特定属性

  if (element.tagName === "BUTTON") {
    // 获取按钮的文本内容（包括所有子元素）
    result.textContent = element.textContent || ""; // return result
  } else if (element.tagName === "IMG") {
    var img = element;
    result.src = "";
    result.alt = img.alt || "";
  } // 处理有ID的元素


  if (element.id) {
    return _objectSpread2(_objectSpread2({}, result), {}, {
      path: "//*[@id=\"".concat(element.id, "\"]")
    });
  } // 处理body元素


  if (element === document.body) {
    return _objectSpread2(_objectSpread2({}, result), {}, {
      path: "BODY"
    });
  } // 处理html元素


  if (element === document.documentElement) {
    return _objectSpread2(_objectSpread2({}, result), {}, {
      path: "HTML"
    });
  } // 没有父元素的情况


  if (!element.parentElement) {
    return _objectSpread2(_objectSpread2({}, result), {}, {
      path: element.tagName
    });
  } // 只考虑元素节点 (Node.ELEMENT_NODE)


  var siblings = Array.from(element.parentElement.children).filter(function (sibling) {
    return sibling.nodeType === Node.ELEMENT_NODE;
  });

  for (var i = 0; i < siblings.length; i++) {
    var sibling = siblings[i];

    if (sibling === element) {
      // found = true;
      // 递归获取父元素路径
      var parentResult = getPathTo(element.parentElement);

      if (!parentResult) {
        return result;
      }

      var tagName = element.tagName; // 计算相同类型元素的位置

      var sameTypeIndex = 1;

      for (var j = 0; j < i; j++) {
        if (siblings[j].tagName === element.tagName) {
          sameTypeIndex++;
        }
      }

      var path = (parentResult === null || parentResult === void 0 ? void 0 : parentResult.path) || parentResult;

      if (path.includes('BUTTON')) {
        var textContent = element.textContent;
        return _objectSpread2(_objectSpread2({}, result), {}, {
          textContent: textContent,
          node: 'BUTTON',
          // 路径格式: 父路径/标签名[相同类型索引]
          path: "".concat(path, "/").concat(tagName, "[").concat(sameTypeIndex, "]")
        });
      } else {
        var src = element.src;
        return _objectSpread2(_objectSpread2({}, result), {}, {
          src: src,
          // 路径格式: 父路径/标签名[相同类型索引]
          path: "".concat(path, "/").concat(tagName, "[").concat(sameTypeIndex, "]")
        });
      }
    }
  } // 如果没有找到元素（理论上不应该发生）


  return _objectSpread2(_objectSpread2({}, result), {}, {
    path: element.tagNames
  });
};
var getImgButtonPath = function getImgButtonPath(element) {
  var data = getPathTo2(element);

  if (data.path && (data.path.includes('IMG') || data.path.includes('BUTTON'))) {
    if (data.src) {
      data.src = data.src.substring(0, 100);
    }

    return data;
  } else {
    return null;
  }
};

var WebMonitorSDK = /*#__PURE__*/function () {
  function WebMonitorSDK() {
    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

    _classCallCheck(this, WebMonitorSDK);

    this.options = options;
    this.deviceId = this.initializeDeviceId();
  } // 初始化设备ID


  _createClass(WebMonitorSDK, [{
    key: "initializeDeviceId",
    value: function initializeDeviceId() {
      return this.getIDFromStorage() || this.getWindowNameID() || this.generateNewDeviceId();
    } // 多级存储查找（新增sessionStorage）

  }, {
    key: "getIDFromStorage",
    value: function getIDFromStorage() {
      return this.readStorage('localStorage') || this.readStorage('sessionStorage') || this.readCookie();
    } // 统一存储接口

  }, {
    key: "readStorage",
    value: function readStorage(type) {
      try {
        return window[type].getItem('_mon_device_id');
      } catch (e) {
        return null;
      }
    } // Cookie读取（带兼容处理）

  }, {
    key: "readCookie",
    value: function readCookie() {
      try {
        var match = document.cookie.match('(^|;)\\s*_mon_device_id\\s*=\\s*([^;]+)');
        return match ? decodeURIComponent(match[2]) : null;
      } catch (e) {
        return null;
      }
    } // 使用window.name作为跨会话后备存储

  }, {
    key: "getWindowNameID",
    value: function getWindowNameID() {
      try {
        if (window.name && /^mondevid-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(window.name)) {
          return window.name.split('mondevid-')[1];
        }
      } catch (e) {}

      return null;
    } // 生成新ID（带类型后缀）

  }, {
    key: "generateNewDeviceId",
    value: function generateNewDeviceId() {
      console.log(this.createUUID(), 'this.createUUID()');
      var deviceId = "".concat(this.createUUID(), "-").concat(this.getStorageTypeSuffix());
      this.saveIDToStorage(deviceId);
      this.saveWindowName(deviceId);
      return deviceId;
    } // 获取存储类型后缀

  }, {
    key: "getStorageTypeSuffix",
    value: function getStorageTypeSuffix() {
      if (this.isStorageAvailable('localStorage')) return 'ls';
      if (this.isStorageAvailable('sessionStorage')) return 'ss';
      if (this.isCookieAvailable()) return 'ck';
      return 'mem';
    } // 检测存储可用性

  }, {
    key: "isStorageAvailable",
    value: function isStorageAvailable(type) {
      try {
        var storage = window[type];
        storage.setItem('test', 'test');
        storage.removeItem('test');
        return true;
      } catch (e) {
        return false;
      }
    } // 检测Cookie可用性

  }, {
    key: "isCookieAvailable",
    value: function isCookieAvailable() {
      try {
        document.cookie = 'test=1;SameSite=Lax';
        return document.cookie.indexOf('test=') !== -1;
      } catch (e) {
        return false;
      }
    } // 统一保存到所有可用存储

  }, {
    key: "saveIDToStorage",
    value: function saveIDToStorage(deviceId) {
      this.saveToStorage('localStorage', deviceId);
      this.saveToStorage('sessionStorage', deviceId);
      this.saveCookie(deviceId);
    } // 通用存储保存方法

  }, {
    key: "saveToStorage",
    value: function saveToStorage(type, deviceId) {
      try {
        window[type].setItem('_mon_device_id', deviceId);
      } catch (e) {}
    } // Cookie保存（带特性检测）

  }, {
    key: "saveCookie",
    value: function saveCookie(deviceId) {
      try {
        if (!navigator.cookieEnabled) return;
        var date = new Date();
        date.setFullYear(date.getFullYear() + 1);
        document.cookie = "_mon_device_id=".concat(encodeURIComponent(deviceId), ";expires=").concat(date.toUTCString(), ";path=/;SameSite=Lax");
      } catch (e) {}
    } // 保存到window.name（作为最后后备）

  }, {
    key: "saveWindowName",
    value: function saveWindowName(deviceId) {
      try {
        window.name = "mondevid-".concat(deviceId);
      } catch (e) {}
    } // 生成UUID（RFC4122兼容）

  }, {
    key: "createUUID",
    value: function createUUID() {
      var cryptoObj = window.crypto || window.msCrypto;

      if (cryptoObj && cryptoObj.getRandomValues) {
        var buffer = new Uint16Array(8);
        cryptoObj.getRandomValues(buffer);
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
          var r = (buffer[0] + performance.now()) % 16 | 0;
          buffer[0] = r;
          return (c === 'x' ? r : r & 0x3 | 0x8).toString(16);
        });
      }

      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0;
        var v = c === 'x' ? r : r & 0x3 | 0x8;
        return v.toString(16);
      });
    } // 重置设备ID

  }, {
    key: "resetDeviceId",
    value: function resetDeviceId() {
      var newId = this.generateNewDeviceId();
      this.deviceId = newId;
    }
  }]);

  return WebMonitorSDK;
}();

/**
 * 添加用户的额外信息
 * @param {string} info 
 */
function extraUserInfo(info) {
  if (info) {
    window["_monitor_user_info_"] = info;
  }
}

/**
 * 初始化配置
 * @param {*} options 
 */

function init(options) {
  // ------- 加载配置 ----------
  // 1.拿到配置信息 
  // 2.注入监控代码
  loadConfig(options); // -------- uv统计 -----------

  lazyReport('user', '加载应用'); // ------ 防止卸载时还有剩余的埋点数据没发送 ------

  window.addEventListener('unload', function () {
    var data = getCache();
    report$1(data); // if (data.length > 0) {
    //   report(data);
    // }
  });
}

var monitor = new WebMonitorSDK({});
var deviceId = monitor.deviceId;

export { deviceId, errorCaptcher, extraUserInfo, init, tracker };
